#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@NAME          : xiaomi_ftp_buss.py
@TIME          : 2025/02/08 14:05:49
@AUTHOR        : chenlip
@VERSION       : 0.0.1
@DESCRIPTION   : 用于小米手机FTP业务的工具类

                应用场景：
                1- 小米手机FTP服务
                2- 每次（没有固定频率）从FTP服务器下载文件到本地指定日期的文件夹

'''
# --------------------------引用--------------------------
import os, sys, json
from datetime import datetime

from app.common.ftp_util import FTPUtil
from app.common.logutil import Loggers
from app.common.utils import Utils as ut
from app.common.file_utils import FileSetter
from app.common.media_sqlite import MediaSqliteAct
# --------------------------引用--------------------------

    

class XiaomiFTPBuss(object):
    
    def __init__(self, confdict:dict=None):
        '''
            连接到FTP服务器
            :Args:
                - confdict: 配置字典
                    - FTP_SERVER: FTP服务器地址
                    - FTP_PORT: FTP服务器端口
                    - FTP_USER: FTP用户名
                    - FTP_PASSWORD: FTP密码
                    - ALL_FILE_LIST: 所有文件列表
                    - FTP_FILE_PATH: FTP文件路径
                    - LOCAL_FTP_BASE: 本地FTP文件路径
                    - LOCAL_FILE_PATH: 本地文件路径
                    - LAST_DOWNLOAD_RECORD_TXT: 最后一次下载记录的txt文件

        '''
        ftp_path = "/Pictures/news_article"
        l_path = r'D:\toutiao\pic'
        
        if confdict is None:
            self.FTP_SERVER = "192.168.2.30"
            self.FTP_PORT = 2121
            self.FTP_USER = "hoeking"
            self.FTP_PASSWORD = "1234567890"
            self.ALL_FILE_LIST = []
            # FTP文件路径
            self.FTP_FILE_PATH = ftp_path
            # 本地文件路径
            self.LOCAL_FTP_BASE= l_path
            # ftp文件下载到本地的文件路径
            self.LOCAL_FILE_PATH = os.path.join(self.LOCAL_FTP_BASE, ut.CURDAY) 
            # 最后一次下载记录的txt文件, 2025-02-05 10:03:32,2025-02-04 11:22:32,abc.jpg
            self.LAST_DOWNLOAD_RECORD_TXT = os.path.join(self.LOCAL_FTP_BASE, "last_download_record.txt")
        else:
            self.FTP_SERVER = confdict.get("FTP_SERVER", "192.168.2.30")
            self.FTP_PORT = confdict.get("FTP_PORT", 2121)
            self.FTP_USER = confdict.get("FTP_USER", "hoeking")
            self.FTP_PASSWORD = confdict.get("FTP_PASSWORD", "1234567890")
            self.ALL_FILE_LIST = confdict.get("ALL_FILE_LIST", [])
            self.FTP_FILE_PATH = confdict.get("FTP_FILE_PATH", ftp_path)
            self.LOCAL_FTP_BASE= confdict.get("LOCAL_FTP_BASE", l_path)
            self.LOCAL_FILE_PATH = confdict.get("LOCAL_FILE_PATH", os.path.join(self.LOCAL_FTP_BASE, ut.CURDAY))
            
            self.LAST_DOWNLOAD_RECORD_TXT = confdict.get("LAST_DOWNLOAD_RECORD_TXT", os.path.join(self.LOCAL_FTP_BASE, "last_download_record.txt"))

        os.makedirs(self.LOCAL_FILE_PATH, exist_ok=True)

        self.ftp = FTPUtil(self.FTP_SERVER, self.FTP_USER, self.FTP_PASSWORD, self.FTP_PORT)

        # 读取最后一次下载记录
        self.last_d_time = None
        _last_d_r = self._read_last_download_record()
        if len(_last_d_r) > 0:
            print(f"读取到最后一次下载记录: {_last_d_r}")
            self.last_d_time = datetime.strptime(_last_d_r[0], "%Y-%m-%d %H:%M:%S")

        # 获取一个数据库对象，用于存储下载的文件信息
        self.sqlite_act = MediaSqliteAct(os.path.join(l_path, "mediares.db"))
        
    def _append_last_download_record(self, fname: str, modify_time: str):
        '''
            追加最后一次下载记录到txt文件的最上面一行.
            :Args:
                - fname: 文件名
                - modify_time: 文件修改时间
        '''
        if not os.path.exists(self.LAST_DOWNLOAD_RECORD_TXT):
            with open(self.LAST_DOWNLOAD_RECORD_TXT, 'w') as f:
                f.write(f"{ut.CURTIME},{modify_time},{fname}\n")
        else:
            with open(self.LAST_DOWNLOAD_RECORD_TXT, 'r+') as f:
                lines = f.readlines()
                f.seek(0)
                f.write(f"{ut.CURTIME},{modify_time},{fname}\n")
                f.writelines(lines)

    def _read_last_download_record(self) -> list:
        '''
            读取最后一次下载记录的txt文件, 读取第一行数据，
            :Return: 
                - last_download_record: 最后一次下载记录，[2025-02-05 10:03:32,2025-02-04 11:22:32,abc.jpg]
        '''
        _last_d_r = []
        if not os.path.exists(self.LAST_DOWNLOAD_RECORD_TXT):
            return _last_d_r
        
        with open(self.LAST_DOWNLOAD_RECORD_TXT, 'r') as f:
            line = f.readline()
            if line:
                _last_d_r = line.strip().split(',')
        
        return _last_d_r


    def get_ftp_file_list(self, ftp_file_path: str, limitdate:str=None):
        '''
            获取指定日期之后的FTP文件列表, 如果没有最后一次下载日期，则使用指定的日期；
            :Args:
                - ftp: FTPUtil对象
                - ftp_file_path: FTP文件路径
                - limitdate: 指定日期

            :Return: 
                - file_list: 指定日期的FTP文件列表， [{'name': 'file1.txt', 'size': 1024, 'modify_time': '2023-07-01 12:00:00'}, ...]
        '''
        # Assuming var is a path on the FTP server
        file_list = self.ftp.get_ftp_list_file(ftp_file_path)  # 这个方法已经按修改时间进行倒序，从新到旧

        if self.last_d_time is None:
            limitdate = datetime.strptime(limitdate, "%Y-%m-%d %H:%M:%S")
            file_list = [file for file in file_list if datetime.strptime(file['modify_time'],"%Y-%m-%d %H:%M:%S") >= limitdate]
            
        else:
            # 按最后一次记录的文件时间获取文件列表
            file_list = [file for file in file_list if datetime.strptime(file['modify_time'],"%Y-%m-%d %H:%M:%S") >= self.last_d_time]

        file_list.sort(key=lambda x: x['modify_time'], reverse=True) # 按修改时间倒序
        
        return file_list
    
    def gen_file_info(self, file_info:dict):
        '''
            生成文件信息，用于插入到数据库中

            :Args:
                - file_info: FTP文件信息
                    - name: 文件名
                    - size: 文件大小(字节)
                    - type: 文件类型('file'或'dir')
                    - modify_time: 修改时间
                
            :Return: 
                - 用户插入数据的结构
                {
                    "source": "baidupan",
                    "file_id": "676233b22f4b615ce0cf4922b4086e74c227474f",
                    "cpath": "/", # 云端路径
                    "lpath": "/", # 本地路径
                    "fname": "IMG_20210101_000001.jpg",
                    "ext": "jpg",
                    "size": 123456,
                    "box":[], # width, height
                    "created_at": "2021-02-01 10:03:32", # 云端创建时间
                    "updated_at": "2021-02-01 10:03:32", # 云端更新时间
                    "local_created_at": "2021-01-01 11:03:32", # 本地创建时间
                    "local_modified_at": "2021-01-02 08:00:01", # 本地更新时间
                    "watermark": {}, # 水印信息
                    "exif": {}, # 图片的exif信息
                    "metadata": {}, # 图片的元数据，可以包含图片的理解文本和标签
                    "s3_urls": {}, # 图片的S3地址
                    "status": "1", # 文件状态
                    "note": "no" # 文件备注
                }

        '''
        _r_dict = ut.BASE_IMAGE_FILE.copy()
        _box = ut.get_image_size(os.path.join(self.LOCAL_FILE_PATH, file_info['name']))

        _r_dict['source'] = 'xiaomi-ftp'
        _r_dict['file_id'] = 'no'
        _r_dict['cpath'] = self.FTP_FILE_PATH
        _r_dict['lpath'] = self.LOCAL_FILE_PATH
        _r_dict['fname'] = file_info['name']
        _r_dict['ext'] = os.path.splitext(file_info['name'])[1].lower()[1:]
        _r_dict['box'] = _box
        _r_dict['size'] = file_info['size']
        _r_dict['created_at'] = ut.CURTIME
        _r_dict['updated_at'] = ut.CURTIME
        _r_dict['local_created_at'] = file_info['modify_time']
        _r_dict['local_modified_at'] = file_info['modify_time']
        _r_dict['status'] = '1'

        return _r_dict
    
    # 数据插入到sql数据库中
    def insert_data(self, file_info:dict):
        '''
            数据插入到sql数据库中
        '''
        _r_dict = self.gen_file_info(file_info)
        return self.sqlite_act.insert_data(_r_dict)

    # 下载文件到本地
    def download_files(self, file_list: list):
        '''
            下载文件到本地
            :Args:
                - file_list: FTP文件列表
        '''
        _err_index = [] # 下载失败的索引列表
        for file in file_list:
            _i = file_list.index(file)
            file_name = file['name']
            file_size = file['size']
            file_modify_time = file['modify_time'] # 原始文件时间
            file_path = os.path.join(self.LOCAL_FILE_PATH, file_name)
            
            if not os.path.exists(file_path):
                isok = self.ftp.download_file(os.path.join(self.FTP_FILE_PATH, file_name), self.LOCAL_FILE_PATH)
                if isok:
                    print(f"{file_name} 下载成功..")
                    # 修改本地文件的创建时间和修改时间
                    FileSetter.set_creation_time(file_path, file_modify_time)
                    # 将文件详细信息加入到sqlite3数据表中
                    self.insert_data(file)
                    # 记录最后一次下载记录
                    if _i == 0:
                        self._append_last_download_record(file_name, file_modify_time)

                else:
                    print(f"{file_name} 下载失败..")
                    _err_index.append(_i)
            else:
                print(f"{file_name} 已经存在..，不再下载")

if __name__ == '__main__':
    xmftp = XiaomiFTPBuss()

    _ftp_file_list = xmftp.get_ftp_file_list(xmftp.FTP_FILE_PATH, limitdate="2025-02-04 11:22:32")
